package com.koron.system.staff.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.koron.bean.base.BaseQueryBean;
import com.koron.bean.system.org.dto.OrgDto;
import com.koron.bean.system.staff.StaffBean;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.business.system.tree.TreeUtil;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.HanyupinyinUtil;
import com.koron.system.common.util.MD5Utils;
import com.koron.system.common.util.UnifyPlatUtils;
import com.koron.system.org.bean.UnifyOrgBean;
import com.koron.system.org.service.OrgService;
import com.koron.system.staff.bean.UnifyStaffBean;
import com.koron.system.staff.bean.dto.OrgDepartmentDto;
import com.koron.system.staff.mapper.UnifyUserMapper;
import com.koron.system.staff.service.StaffService;
import com.koron.system.staff.service.UnifyUserService;
import com.koron.system.userOrg.bean.po.AppUserOrgPo;
import com.koron.system.userOrg.service.AppUserOrgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName UnifyUserServiceImpl
 * @description
 * @Author zhouj
 * @Date 2021/7/8 15:10
 */
@Slf4j
@Transactional
@Service
public class UnifyUserServiceImpl implements UnifyUserService {

    @Autowired
    UnifyUserMapper unifyUserMapper;

    @Autowired
    StaffService staffService;

    @Autowired
    OrgService orgService;

    @Autowired
    AppUserOrgService appUserOrgService;

    private UnifyPlatUtils unifyPlatUtils = new UnifyPlatUtils();

    @Override
    public List<UnifyOrgBean> getOrgNodeTree(Map<String, String> cond) {

        JSONArray jsonArray = unifyPlatUtils.getOrgNode(cond);

        List<UnifyOrgBean> unifyOrgBeans = JSONArray.parseArray(jsonArray.toJSONString(), UnifyOrgBean.class);

        unifyOrgBeans.forEach(p -> {
            p.setParentid(p.getParentCode());
            p.setId(p.getCode());
            p.setOrder(p.getWeight() == null ? 1 : p.getWeight());
        });

        List<UnifyOrgBean> tree = TreeUtil.getTree(unifyOrgBeans);

        return tree;
    }

    @Override
    public List<UnifyOrgBean> getOrgNode(Map<String, String> cond) {

        JSONArray jsonArray = unifyPlatUtils.getOrgNode(cond);

        List<UnifyOrgBean> unifyOrgBeans = JSONArray.parseArray(jsonArray.toJSONString(), UnifyOrgBean.class);

        return unifyOrgBeans;
    }

    @Override
    public int inUpAllOrgNode(Map<String, String> cond) {
        List<UnifyOrgBean> orgNodes = getOrgNode(cond);
        orgNodes.forEach(p -> {
            p.setOrgId(CodeTools.getCode32());
            p.setUpdateTime(new Date());
        });
        return unifyUserMapper.inUpAllOrgNode(orgNodes);
    }

    @Override
    public List<UnifyStaffBean> getStaff(Map<String, String> cond) {
        JSONArray jsonArray = unifyPlatUtils.getStaff(cond);


        List<UnifyStaffBean> unifyOrgBeans = JSONArray.parseArray(jsonArray.toJSONString(), UnifyStaffBean.class);

        if (CollectionUtils.isNotEmpty(unifyOrgBeans)) {

            for (int y = 0; y < unifyOrgBeans.size(); y++) {
                UnifyStaffBean next = unifyOrgBeans.get(y);
                List<OrgDepartmentDto> orgDepartmentDtos = next.getOrgDepartments();
                next.setOrgDepartments(null);
                if (CollectionUtils.isEmpty(orgDepartmentDtos)) {
                    continue;
                }
                next.setOrgNodeCode(orgDepartmentDtos.get(0).getDepartmentCode());
                next.setOrgNodeName(orgDepartmentDtos.get(0).getDepartmentName());
                if (orgDepartmentDtos.size() > 1) {
                    for (int i = 1; i < orgDepartmentDtos.size(); i++) {
                        UnifyStaffBean unifyStaffBean = new UnifyStaffBean();
                        BeanUtils.copyProperties(next, unifyStaffBean);
                        unifyStaffBean.setOrgNodeCode(orgDepartmentDtos.get(i).getDepartmentCode());
                        unifyStaffBean.setOrgNodeName(orgDepartmentDtos.get(i).getDepartmentName());
                        unifyStaffBean.setOrgDepartments(null);
                        unifyOrgBeans.add(unifyStaffBean);
                    }
                }
            }
        }

        return unifyOrgBeans;
    }

    @Override
    public int inUpAllStaff(Map<String, String> cond) {
        List<UnifyStaffBean> staffs = getStaff(cond);

        Map<String, String> map = ConfigInfoTool.getConfigByCode("system", "org");
        String environment = map.get("environment");

        switch (environment) {
            case "eam":
                staffs.forEach(p -> {
                    p.setUpdateTime(new Date());
                    p.setId(CodeTools.getCode32());
                });
                break;
            case "yc":
                staffs.forEach(p -> {
                    p.setPhone(StringUtils.isEmpty(p.getMobile()) ? p.getPhone() : p.getMobile());
                    p.setLoginName(p.getCode());
                    p.setUpdateTime(new Date());
                    p.setId(CodeTools.getCode32());
                });
                break;
            default:
                staffs.forEach(p -> {
                    p.setUpdateTime(new Date());
                    p.setId(CodeTools.getCode32());
                });
                break;
        }

        Iterator<UnifyStaffBean> iterator = staffs.iterator();
        while (iterator.hasNext()) {
            UnifyStaffBean next = iterator.next();
            if (StringUtils.isEmpty(next.getLoginName())) {
                log.info("loginName为空:{}", next.toString());
                iterator.remove();
            }
        }
        return unifyUserMapper.inUpAllStaff(staffs);
    }

    @Override
    public List<StaffBean> queryStaffList(UnifyStaffBean unifyStaffBean, BaseQueryBean queryBean) {
        return unifyUserMapper.queryStaffList(unifyStaffBean, queryBean);
    }

    public List<StaffBean> queryStaffListWithNoPage(UnifyStaffBean unifyStaffBean) {
        return unifyUserMapper.queryStaffListWithNoPage(unifyStaffBean);
    }

    @Override
    public Long queryStaffListCount(UnifyStaffBean unifyStaffBean) {
        return unifyUserMapper.queryStaffListCount(unifyStaffBean);
    }

    @Override
    public List<UnifyOrgBean> queryOrgNodeList(UnifyOrgBean unifyOrgBean) {
        List<UnifyOrgBean> unifyOrgBeans = unifyUserMapper.queryOrgNodeList(unifyOrgBean);
        unifyOrgBeans.forEach(p -> {
            p.setId(p.getCode());
            p.setParentid(p.getParentCode());
            p.setOrder(p.getOrder() == null ? 1 : p.getOrder());
        });
        List<UnifyOrgBean> treeList = TreeUtil.getTree(unifyOrgBeans);
        return treeList;
    }

    public int batchInsertOrg(List<OrgDto> orgDtoList) {

        EamUser eamUser = ThreadLocalContext.getLoginUser();

        //新增组织得 生成好全路径,存入数据库/添加组织首拼
        int i = 0;
        if (CollectionUtils.isEmpty(orgDtoList)) {
            return i;
        }
        orgDtoList.forEach(p -> {

            p.setId(StringUtils.isEmpty(p.getId()) ? CodeTools.getCode32() : p.getId());
            p.setCreateBy(eamUser.getAccount());
            p.setCreateByName(eamUser.getName());
            p.setCreateTime(new Date());

        });

        i = unifyUserMapper.batchInsertOrg(orgDtoList);
        return i;
    }

    @Override
    public int initOrg(UnifyOrgBean unifyOrgBean) {
        //根据集团组织树父节点,初始化节点下组织及人员 到临时组织表,人员表
        //1.根据code找到目标组织树节点
        List<UnifyOrgBean> search = search(unifyOrgBean.getCode());
        //2.转化为自有组织
        if (CollectionUtils.isEmpty(search)) {
            return 0;
        }
        List<OrgDto> orgDtos = convertorOrg(search, new ArrayList<>(), "/", "/", null, 1);
        //根据组织找到集团的人员
        Assert.notEmpty(orgDtos, "组织数据不能为空");
        Map<String, String> map = new HashMap<>();
        orgDtos.forEach(p -> {
            p.setId(p.getCode());
            p.setNamePy(HanyupinyinUtil.getPinyinString(p.getName()));
            p.setPrefix(HanyupinyinUtil.getFirstLettersUpper(p.getName()));
            map.put(p.getCode(), p.getId());
        });

        batchInsertOrg(orgDtos);

        List<String> orgIdList = orgDtos.stream().map(OrgDto::getCode).collect(Collectors.toList());

        UnifyStaffBean unifyStaffBean = new UnifyStaffBean();
        unifyStaffBean.setOrgIdList(orgIdList);
        List<StaffBean> staffBeanList = queryStaffListWithNoPage(unifyStaffBean);

        if (CollectionUtils.isNotEmpty(staffBeanList)) {
            staffBeanList.forEach(p -> {
                p.setOrgId(map.get(p.getOrgId()));
                p.setPassword(getInitPassWord());
            });
        }

        //将集团人员转化为自有人员
        batchInUpUser(staffBeanList);

        //入库组织数据
        List<AppUserOrgPo> userOrgPos = new ArrayList<>();
        staffBeanList.forEach(p -> {
            AppUserOrgPo userOrgPo = new AppUserOrgPo();
            userOrgPo.setAccount(p.getAccount());
            userOrgPo.setOrgId(p.getOrgId());
            //userOrgPo.setDefaultFlag();
            userOrgPos.add(userOrgPo);
        });
        unifyUserMapper.batchInUpUserOrg(userOrgPos);

        return 0;
    }

    @Override
    public int syncOrg(UnifyOrgBean unifyOrgBean) {

        try {
            //1.根据code找到目标组织树节点
            List<UnifyOrgBean> search = search(unifyOrgBean.getCode());
            //2.转化为自有组织
            if (CollectionUtils.isEmpty(search)) {
                return -1;
            }
            String levelPathName = "/";
            String levelPath = "/";
            int level = 0;
            String parent = null;
            UnifyOrgBean parentUnifyOrgBean = null;

            if (unifyOrgBean.getParentCode().equals("0")) {

                level++;
                parent = null;
            }
            parentUnifyOrgBean = unifyOrgBean;

            //else {
            //    if (StringUtils.isNotBlank(unifyOrgBean.getParentCode())) {
            //        parentUnifyOrgBean = unifyUserMapper.queryOrgNode(unifyOrgBean.getParentCode());
            //    }
            //}
            while (true) {

                parentUnifyOrgBean = unifyUserMapper.queryOrgNode(parentUnifyOrgBean.getParentCode());
                if (Objects.isNull(parentUnifyOrgBean) || "0".equals(parentUnifyOrgBean.getParentCode())) {
                    break;
                }
                level++;
                levelPath = "/" +parentUnifyOrgBean.getCode() + levelPath;
                levelPathName = "/" +parentUnifyOrgBean.getName() + levelPathName;
            }
            if (Objects.nonNull(parentUnifyOrgBean)){
                levelPath += parentUnifyOrgBean.getCode();
                levelPathName += parentUnifyOrgBean.getShortName();
            }

            levelPath = levelPath.replaceAll("/+", "/");
            levelPathName = levelPathName.replaceAll("/+", "/");

            List<OrgDto> orgDtos = convertorOrg(search, new ArrayList<>(), levelPathName, levelPath, parent, level);
            Assert.notEmpty(orgDtos, "组织数据不能为空");

            // 过滤出当前节点下的子节点
            if (!unifyOrgBean.isNeedParent()) {
                orgDtos = orgDtos.stream().filter(o -> !unifyOrgBean.getCode().equals(o.getCode())).collect(Collectors.toList());
            }

            //orgDtos = orgDtos.stream().sorted(Comparator.comparing(OrgDto::getLevel).thenComparing(OrgDto::getCode)).collect(Collectors.toList());

            for (int i = 0; i < orgDtos.size(); i++) {
                OrgDto orgDto = orgDtos.get(i);
                orgDto.setId(orgDto.getCode());
                orgDto.setNamePy(HanyupinyinUtil.getPinyinString(orgDto.getName()));
                orgDto.setPrefix(HanyupinyinUtil.getFirstLettersUpper(orgDto.getName()));
                orgDto.setAppid(unifyOrgBean.getAppId());
            }
            int result = batchInsertOrg(orgDtos);
            return result;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("当前编码节点已存在，请勿重复添加！");
        }
    }

    //@Override
    //public int syncOrg(UnifyOrgBean unifyOrgBean) {
    //    //根据集团组织树父节点,初始化节点下组织及人员 到临时组织表,人员表
    //    //1.根据code找到目标组织树节点
    //    List<UnifyOrgBean> search = search(unifyOrgBean.getCode());
    //    //2.转化为自有组织
    //    if (CollectionUtils.isEmpty(search)) {
    //        return -1;
    //    }
    //    UnifyOrgBean parentUnifyOrgBean = null;
    //    int level = 0;
    //    String levelPathName = "/";
    //    String levelPath = "/";
    //    if(StringUtils.isNotBlank(unifyOrgBean.getParentCode())){
    //        parentUnifyOrgBean  = unifyUserMapper.queryOrgNode(unifyOrgBean.getParentCode());
    //    }
    //
    //    if (Objects.isNull(parentUnifyOrgBean)){
    //        return -1;
    //    }
    //
    //    while(true){
    //        level++;
    //        UnifyOrgBean parent = unifyUserMapper.queryOrgNode(parentUnifyOrgBean.getParentCode());
    //        if (Objects.isNull(parent)){
    //            break;
    //        }
    //        levelPath += parent.getCode() + "/";
    //        levelPathName += parent.getName() + "/";
    //    }
    //    levelPath += parentUnifyOrgBean.getCode();
    //    levelPathName += parentUnifyOrgBean.getShortName();
    //    List<OrgDto> orgDtos = convertorOrg(search, new ArrayList<>(), levelPathName, levelPath, parentUnifyOrgBean.getCode(), level);
    //    //根据组织找到集团的人员
    //    Assert.notEmpty(orgDtos, "组织数据不能为空");
    //    Map<String, String> map = new HashMap<>();
    //    orgDtos.forEach(p -> {
    //        p.setId(p.getCode());
    //        p.setNamePy(HanyupinyinUtil.getPinyinString(p.getName()));
    //        p.setPrefix(HanyupinyinUtil.getFirstLettersUpper(p.getName()));
    //        map.put(p.getCode(), p.getId());
    //    });
    //
    //    int result = batchInsertOrg(orgDtos);
    //
    //    return result;
    //}

    public String getInitPassWord() {

        Map<String, String> configByCode = ConfigInfoTool.getConfigByCode("system", "system_login_config");

        return configByCode.getOrDefault("init_password", "hello123&");
    }

    public int batchInUpUser(List<StaffBean> staffBeans) {

        EamUser user = ThreadLocalContext.getLoginUser();

        staffBeans.forEach(p -> {
            p.setId(p.getAccount());
            p.setCreateBy(user.getAccount());
            p.setCreateByName(user.getName());
            p.setCreateTime(new Date());
            p.setNamePy(HanyupinyinUtil.getPinyinString(p.getName()));
            if (!StringUtils.isEmpty(p.getPassword())) {
                p.setPassword(MD5Utils.md5(p.getPassword()));
            }
        });
        return unifyUserMapper.batchInsertStaff(staffBeans);
    }

    private List<OrgDto> convertorOrg(List<UnifyOrgBean> search, List<OrgDto> orgDtos, String levelPathName, String levelPath, String parent, int level) {
        if (CollectionUtils.isEmpty(search)) {
            return null;
        }

        for (UnifyOrgBean unifyOrgBean : search) {

            OrgDto dto = new OrgDto();
            dto.setId(CodeTools.getCode32());
            dto.setParent(parent);
            dto.setLevelPathName(levelPathName);
            dto.setLevelPath(levelPath);
            dto.setLevel(String.valueOf(level));
            dto.setName(unifyOrgBean.getName());
            dto.setOutOrg("0");
            dto.setSort(unifyOrgBean.getOrder());
            dto.setCode(unifyOrgBean.getCode());
            dto.setParentCode(unifyOrgBean.getParentCode());
            orgDtos.add(dto);
            List<UnifyOrgBean> children = unifyOrgBean.getChildren();
            if (CollectionUtils.isNotEmpty(children)) {
                String nextLevelPathName = "";
                String nextLevelPath = "";
                if (!StringUtils.equals(dto.getLevelPathName(), "/")) {
                    nextLevelPathName = dto.getLevelPathName() + "/";
                    nextLevelPath = dto.getLevelPath() + "/";
                } else {
                    nextLevelPathName = dto.getLevelPathName();
                    nextLevelPath = dto.getLevelPath();
                }
                convertorOrg(children, orgDtos, nextLevelPathName + dto.getName(), nextLevelPath + dto.getCode(), dto.getCode(), level + 1);
            }

        }
        return orgDtos;
    }

    public List<UnifyOrgBean> search(String code) {
        List<UnifyOrgBean> unifyOrgBeans = queryOrgNodeList(new UnifyOrgBean());
        if (StringUtils.isEmpty(code)) {
            return unifyOrgBeans;
        }
        return search1(unifyOrgBeans, code);

    }

    public List<UnifyOrgBean> search1(List<UnifyOrgBean> unifyOrgBeans, String code) {
        if (CollectionUtils.isNotEmpty(unifyOrgBeans)) {
            for (UnifyOrgBean p : unifyOrgBeans) {
                if (p.getCode().equals(code)) {
                    List<UnifyOrgBean> list = new ArrayList<UnifyOrgBean>();
                    list.add(p);
                    return list;
                }
                List<UnifyOrgBean> list = search1(p.getChildren(), code);
                if (CollectionUtils.isNotEmpty(list)) {
                    return list;
                }
            }
        }
        return new ArrayList<UnifyOrgBean>();
    }

}
